#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>

#include "Graph.h"
#include "Sorter.h"
#include "Set.h"

#define PRIM 1
#define BINARY_HEAP 0
#define UNO_ARRAY 1

#define KRUSKAL 0
#define HEAP_SORT 0
#define MERGE_SORT 1
#define BUBBLE_SORT 2

#define MAX_FILE_NAME 80

using namespace std;

int main(int argc, char **argv)
{
	
	char* program_name = argv[0];

	if (argc != 4)
	{
			cout << "Usage: " << program_name << " input_file algorithm_type sort_type" << endl;
			return EXIT_FAILURE;
	}
   
	char* input_file = argv[1];
	int arg_algo = atoi(argv[2]);
	int arg_sort = atoi(argv[3]);      

	Graph::Algorithm algo;

	cout << "Input file: " << input_file << endl;
   
	cout << "Algorithm: ";
	switch (arg_algo)
	{
		case 0 :
			cout << "Kruskal's" << endl;
			
			switch (arg_sort)				
			{
				case 0 :
					algo = Graph::kruskal_heapsort;
					cout << "Sort Type: Heap Sort" << endl;						
					break;
			
				case 1 :					
					algo = Graph::kruskal_mergesort;
					cout << "Sort Type: Merge Sort" << endl;
					break;
					
				case 2 :
					algo = Graph::kruskal_bubblesort;
					cout << "Sort Type: Bubble Sort" << endl;
					break;
					
				default :                
					cout << "Unknown Sort Type" << endl;
					cout << "Usage: " << program_name << " input_file algorithm_type sort_type" << endl;
					return EXIT_FAILURE;
			}
			break;
		
		// Prim
		case 1 :
			cout << "Prim's" << endl;
		   
			switch (arg_sort)
			{
				case 0 :
					algo = Graph::prim_heap;
					cout << "Sort Type: Binary Heap" << endl;
					break;
				case 1 :
					algo = Graph::prim_unordered;
					cout << "Sort Type: Un-ordered array" << endl;
					break;
				default : 			
					cout << "Unknown Sort Type" << endl;
					cout << "Usage: " << program_name << " input_file algorithm_type sort_type" << endl;
					return EXIT_FAILURE;
			}
			break;
			
		// Unknown algo
		default : 
			cout << "Unknown Algoirthm Type" << endl;
			cout << "Usage: " << program_name << " input_file algorithm_type sort_type" << endl;
			return EXIT_FAILURE;
	
	}
	
	// for clock
	clock_t start_t, end_t, elapsed_t;	
	start_t = clock();
	
	Graph graph;
	graph.inputPoints(input_file);	
	graph.calculateMST(algo);
	
	char output_file[MAX_FILE_NAME];
	sprintf(output_file, "output-%d.svg", graph.pointsSize);
	graph.outputMST(output_file);
	
	// Print elasped time
	end_t = clock();
	elapsed_t = end_t - start_t;
	cout << "Total time: " << (double) elapsed_t / CLOCKS_PER_SEC << "s" << endl;

	return EXIT_SUCCESS;
}